#ifndef EVENTS_H
#define EVENTS_H

//bindKeyToEvent(VC_T, C_Event_Chat::getInstance());


//Client has authority on aim direction that gets sent when firing

//Client events sent by client received by server
//Client events activate checks if is actually server acting as client and 
// doesn't call send if so

class C_ClientEvent : INetEvent
{
	
public:
	
	virtual void activate()
	{
		
		if (!IsServer)
			onSend();
		
		onActivate();
		
	}
	
};

class C_StartStopEvent : INetEvent
{
	
public:
	
	CStartStopEvent(bool bIsStart) : m_bIsStart(bIsStart) 		{}
	
private:
	
	bool m_bIsStart;
	
};


if (VC_ENTER == key) {
	
	//Have to give the event the message string and the team index
	//	TODO: What here
	//Have to make the event call the ChatLog appropriatly
	//	activate()
	//Have to make the event send itsself to the server
	//	send()
	
	//C_Event_ChatMessage::getInstance()->setParams(
	
	//Activate the event locally
	C_Event_ChatMessage::getInstance()->activate();
	
	//Let the server know about the event
	C_Event_ChatMessage::getInstance()->send();
	
}

class IEvent
{
public:
	//Note: Do not override this
	virtual void activate() = 0;
protected:
	//Override this to do what the event does locally
	virtual void onActivate() = 0;
};

class CEvent : public IEvent
{
public:
	//Note: Do not override this
	virtual void activate() 		{ onActivate(); }	
};

class INetEvent : public IEvent
{
	
public:
	
	//Note: Do not override this
	virtual void activate() = 0;
	
	//Call this when receiving the event from the network
	void activateFromPacket(Packet* pPacket) 
		{ onReceive(pPacket); onActivate(); }
	
protected:
	
	//Override this to encode the event into a packet and send it over the network
	virtual void onSend(INetworkInterface* pNetwork) = 0;
	
	//Override this to decode the given packet into the event's member data
	virtual void onReceive(Packet* pPacket) = 0;
	
};

//Bound events will be deleted automatically by the binding manager
bindKeyToEvent(VC_T, new C_Event_Chat(sMessage, iTeam) );

C_Event_Chat pEvent(sMessage, iTeam);
pEvent();

//When receive chat message at client
//	Have to give bitstream parameters to event
//		decode(packet)
//	Have to make event call ChatLog appropriatly
// 		activate()

//IEvent
virtual void activate() = 0; 		//Does what the event does

//INetEvent
virtual void send() = 0; 		//Sends the event over the network

virtual void decode(Packet* pPacket) = 0; 		//Decodes the given packet into the event

//Chat event activated at client
class C_Event_Chat : public ouden::IEvent
{
	
public:
	
	C_Event_Chat(ouden::String sMessage, unsigned char iTeam) 
	 : m_iTypeID(ID_CHAT), m_sMessage(sMessage), m_iTeam(iTeam) 		{}
	
protected:
	
	virtual void onActivate()
	{
		
		//TODO: Add message to ChatLog
		
	}
	
	virtual void onSend(/*TODO: Decide here */IClientInterface* pNetwork)
	{
		
		Bitstream bsPacket; 		//Create the packet
		bsPacket.Write(m_iTypeID); 	//Write the type identifier
		bsPacket.Write(m_iTeam); 	//Write the team identifier
		stringCompressor->EncodeString(m_sMessage.c_str(), 256, bsPacket); 	//Encode and write the message string
		
		//pNetwork->send(bsPacket, 
		
	}
	
	virtual void onReceive(Packet* pPacket)
	{
		
		
		
	}
	
private:
	
	unsigned char m_iTypeID;
	unsigned char m_iTeam; 		//0: Global message, else: Index of team message
	String m_sMessage;
	
};

class CPlayerMove_Event : public ouden::INetEvent
{
public:

	//CPlayerMove_Event();
	//virtual ~CPlayerMove_Event();
	
	/// Override this in derived game events to do what the event is supposed to do
	virtual void activate() = 0;
	
	/// Override this to return the event's type as a string
	virtual String getType() = 0;
	
	/// Override this to return a description of the event
	virtual String getDescription() = 0;
	
protected:
private:
	
	
	
};

class IEvent
{
public:

	IEvent();
	virtual ~IEvent();
	
	/// Override this in derived game events to do what the event is supposed to do
	virtual void activate() = 0;
	
	/// Override this to return the event's type as a string
	virtual String getType() = 0;
	
	/// Override this to return a description of the event
	virtual String getDescription() = 0;
	
protected:
private:
};

class INetEvent
{
	
public:
	
	/// Override this to return the game event encoded as a bitstream (char*) for 
	///  sending over the network in a packet
	virtual char* encode() = 0;
	
	/// Override this to decode a given bitstream back into the event's own
	///  data, ready for a call to activate()
	virtual void decode(char* bsBitStream) = 0;
	
};


#endif // EVENTS_H
